<template>
  <div class="form2">
    <el-form class="my-form" :model="formData" ref="form" label-width="150px">
      <el-form-item v-for="(item, key) in labelsData" :key="key" :prop="key" v-show="item.visible !== false" :label="item.label" :rules="getRules(item)">
        <slot :name="key">
          <el-select v-if="item.is === 'el-select'" @change="saveData($event, key)" :value="formData[key]" v-bind="getItemProps(item, key)">
            <el-option v-for="it in item.options" :key="it.value" :value="it.value" :label="it.label"></el-option>
          </el-select>
          <component v-else @change="saveData($event, key)" @input="saveData($event, key)" :is="item.is || 'el-input'" v-bind="getItemProps(item, key)"></component>
        </slot>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
// :is="item.is || item.type || 'el-input'" 记得优化
/**
 * 常用组件合集
 * el-input、my-upload
 */
export default {
  props: {
    record: {
      name: ''
    },
    labels: {
      name: {
        label: '示例'
      }
    }
  },
  data() {
    return {
      formData: { ...this.record },
      pickerOptions: {
        disabledDate(time) {
          return time.getTime() < Date.now()
        }
      }
    }
  },
  computed: {
    labelsData() {
      const labelData = {}
      const mirror = {
        'el-input': ['el-input'],
        'upload-qn': ['qnImage'],
        'drag-upload': ['aliImage'],
        'region-select': ['region'],
        'el-select': ['select'],
        'el-date-picker': ['datetime', 'date', 'daterange'],
        'el-time-picker': ['time'],
        'el-color-picker': ['color']
      }
      Object.entries(this.labels).forEach(([key, item]) => {
        if (typeof item === 'string') {
          labelData[key] = {
            label: item
          }
        } else if (item.is) {
          labelData[key] = item
        } else {
          if (!item.type) {
            item.is = 'el-input'
          } else {
            item.is = Object.keys(mirror).find(key => mirror[key].includes(item.type)) || 'el-input'
          }
          labelData[key] = item
        }
      })
      return labelData
    }
  },
  watch: {
    record(e) { // 保证同步父组件数据
      this.formData = { ...e }
    }
  },
  methods: {
    submit(callback) {
      this.$refs.form.validate((valid) => {
        if (valid) {
          callback(this.formData)
        }
      })
    },
    // eslint-disable-next-line
    getItemProps({ rules, is, type, ...rest }, key) {
      const { formData } = this
      const props = {
        value: formData[key],
        is,
        ...rest
      }
      if (['el-input', 'el-date-picker'].includes(is)) props.type = type
      if (['el-input'].includes(is) || !is) {
        props.placeholder = `请输入${rest.label}`
      }
      return props
    },
    saveData(value, key) { // 保存数据
      this.$set(this.formData, key, value)
    },
    getRules(item) {
      if (item.rules) return item.rules // 默认使用自定义rules
      const validatePhone = (rule, value, callback) => {
        if (!(/^1\d{10}$/.test(value))) {
          callback(new Error('请正确输入手机号'))
        } else {
          callback()
        }
      }
      const rules = { required: true, message: '请输入', trigger: 'blur' }
      const changeRule = { required: true, message: '请选择', trigger: 'change' }
      const phoneRule = [
        { required: true, message: '请输入', trigger: 'blur' },
        { validator: validatePhone, message: '请正确输入手机号', trigger: 'blur' }
      ]
      if (typeof item === 'string') return rules
      if (item.type === 'phone') return phoneRule
      if (['image', 'select'].includes(item.is)) return changeRule
      return rules
    }
  },
  components: {}
}
</script>
